package com.product.android.utils;

import java.util.ArrayList;
import java.util.regex.Matcher;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.TextView;

import com.common.android.utils.UrlUtils;
import com.common.android.utils.smiley.Smiley;
import com.common.android.utils.smiley.Smileyhelper;
import com.nd.android.u.allcommon.R;
import com.product.android.commonInterface.allCommonInterfaceImpl.AllCommonCallOtherModel;
import com.product.android.ui.activity.WebViewActivity;
import com.product.android.utils.wbAtUtils.WbAtInfo;
import com.product.android.utils.wbAtUtils.WbAtView;

/**
 * 内容的各种解析
 * 
 * <br>
 * Created 2014-8-28 下午6:08:01
 * 
 * @version
 * @author PanYun
 * 
 * @see
 */
public final class ContentUtils {
    /**
     * 
     * Creates a new instance of ContentUtils. <br>
     * Created 2014-8-28 下午6:08:20
     */
    private ContentUtils() {
    };

    public static final int SMILEY_SIZE = 18;

    /**
     * 解析全部，包括at人，表情，url,话题
     * 
     * <br>
     * Created 2014-8-28 下午6:08:27
     * 
     * @param context
     *            Context
     * @param sourceContent
     *            要解析的内容
     * @return SpannableString 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveAll(Context context, String sourceContent) {
        String onlyAtContent = WbAtView.getOnlyAtContent(sourceContent);// 剔除<M
                                                                        // XXX></M>,这样界面显示上就不会出现该字段，只显示@XXX，同时不影响其他被解析的字段
        SpannableString ss = Smileyhelper.getInstance().getSmileySpannableString(onlyAtContent,
                Smiley.TYPE_WEIBO, SMILEY_SIZE);
        ss = resolveAt(ss.toString(), sourceContent, ss);
        ss = resolveUrl(context, ss.toString(), ss);
        ss = resolveHashtags(ss.toString(), ss);
        return ss;
    }

    /**
     * 解析表情和url
     * 
     * <br>
     * Created 2014-8-28 下午6:09:09
     * 
     * @param context
     *            Context
     * @param sourceContent
     *            要解析的内容
     * @return SpannableString 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveSmileyUrl(Context context, String sourceContent) {
        SpannableString ss = Smileyhelper.getInstance().getSmileySpannableString(sourceContent,
                Smiley.TYPE_WEIBO, SMILEY_SIZE);
        ss = resolveUrl(context, ss.toString(), ss);
        return ss;
    }

    /**
     * 解析表情,at人名、url
     * 
     * <br>
     * Created 2014-8-28 下午6:09:53
     * 
     * @param context
     *            Context
     * @param sourceContent
     *            要解析的内容
     * @return SpannableString 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveSmileyAtUrl(Context context, String sourceContent) {
        String onlyAtContent = WbAtView.getOnlyAtContent(sourceContent);// 剔除<M
                                                                        // XXX></M>,这样界面显示上就不会出现该字段，只显示@XXX，同时不影响其他被解析的字段
        SpannableString ss = Smileyhelper.getInstance().getSmileySpannableString(onlyAtContent,
                Smiley.TYPE_WEIBO, SMILEY_SIZE);
        ss = resolveAt(ss.toString(), sourceContent, ss);
        ss = resolveUrl(context, ss.toString(), ss);
        return ss;
    }

    /**
     * 微博内容At点击（兼容重名用户）
     * 
     * @n<b>函数名称</b> :resolveAt
     * @brief
     * @see
     * @since Ver 1.1
     * @param onlyAtContent
     *            去除<M></MM>后的内容，在这里把@的人标记出来
     * @param sourceContent
     *            有带<M></MM>的内容，要从这里找出@的人
     * @param ss 含有格式设置的内容
     * @return SpannableString 解析后的内容
     * @<b>作者</b> : 黄永鑫
     * @<b>创建时间</b> : 2014-3-11上午10:21:18
     */
    public static SpannableString resolveAt(String onlyAtContent, String sourceContent,
            SpannableString ss) {
        int start = 0;
        int index = -1;
        ArrayList<WbAtInfo> wbAtInfoList = getNameIdList(sourceContent);
        if (ss == null) {
            ss = new SpannableString(sourceContent);
        }
        if (!TextUtils.isEmpty(onlyAtContent) && wbAtInfoList.size() > 0) {
            for (WbAtInfo info : wbAtInfoList) {
                index = onlyAtContent.indexOf(info.atName, start);
                if (index != -1) {
                    start = index + info.atName.length();
                    ss.setSpan(new URLSpanNoUnderline(info.atName, URLSpanNoUnderline.SpanType.AT,
                            info.atUid), index, start, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
                    index = -1;
                }
            }
        }
        return ss;
    }

    /**
     * 根据服务端返回的字段，解析出AT用户信息列表
     * 
     * @n<b>函数名称</b> :getNameIdList
     * @brief
     * @see
     * @version Ver 1.3.2
     * @param sourceContent
     *            待解析的内容
     * @return ArrayList<WbAtInfo> at的列表
     * @<b>作者</b> : HuangYK
     * @<b>创建时间</b> : 2013-12-17下午9:09:14
     */
    protected static ArrayList<WbAtInfo> getNameIdList(String sourceContent) {
        ArrayList<WbAtInfo> wbAtInfoList = new ArrayList<WbAtInfo>();
        if (TextUtils.isEmpty(sourceContent)) {
            return wbAtInfoList;
        }
        Matcher m = WbRegexUtils.AT_M_TAG_PATTERN.matcher(sourceContent);// find <M
                                                                       // 12345678>@Robinson</M>
        while (m.find()) {
            String strM = m.group();
            Matcher beginM = WbRegexUtils.M_TAG_BEGIN_PATTERN.matcher(strM);// find <M 12345678>
            if (beginM.find()) {
                String strBegin = beginM.group();
                Matcher uidM = WbRegexUtils.AT_UID_PATTERN.matcher(strBegin);// find 12345678
                Matcher atM = WbRegexUtils.AT_USER_PATTERN.matcher(strM);// find @Robinson
                if (atM.find() && uidM.find()) {
                    WbAtInfo wbAtInfo = new WbAtInfo();
                    wbAtInfo.atName = atM.group();
                    wbAtInfo.atUid = Long.valueOf(uidM.group());
                    wbAtInfoList.add(wbAtInfo);
                }
            }
        }
        return wbAtInfoList;
    }

    /**
     * 解析url
     * 
     * <br>
     * Created 2014-8-28 下午6:11:57
     * 
     * @param context
     *            Context
     * @param sourceContent
     *            要解析的内容
     * @param ss
     *            要解析的内容
     * @return SpannableString 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveUrl(Context context, String sourceContent,
            SpannableString ss) {
        if (ss == null) {
            ss = new SpannableString(sourceContent);
        }
        Matcher m = UrlUtils.WEB_URL.matcher(sourceContent);
        while (m.find()) {
            ss.setSpan(new URLImageClickSpan(UrlUtils.makeUrl(m.group()),
                    URLSpanNoUnderline.SpanType.URL), m.start(), m.end(),
                    SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
            UrlImageSpan span = new UrlImageSpan(getImageSpanDrawble(context, false, null));
			span.setUrl(m.group());
            ss.setSpan(span, m.start(),
                    m.end(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);

        }
        return ss;
    }

    /**
     * 用于生日提醒那边高亮显示@XXXX
     * 
     * @n<b>函数名称</b> :resolveAt
     * @brief
     * @see
     * @since Ver 1.1
     * @param sourceContent
     *            待解析的内容
     * @return SpannableString 解析后的内容
     * @<b>作者</b> : 黄永鑫
     * @<b>创建时间</b> : 2013-11-19上午11:57:34
     */
    public static SpannableString resolveAt(String sourceContent) {
        SpannableString ss = new SpannableString(sourceContent);

        Matcher m = WbRegexUtils.AUTO_AT_PATTERN.matcher(sourceContent);
        while (m.find()) {
            ss.setSpan(new URLSpanNoUnderline(m.group()), m.start(), m.end(),
                    SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return ss;
    }

    /**
     * 解析表情
     * 
     * <br>
     * Created 2014-8-28 下午6:18:49
     * 
     * @param context
     *            Context
     * @param sourceContent
     *            待解析的内容
     * @return 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveSmiley(Context context, String sourceContent) {
        return Smileyhelper.getInstance().getSmileySpannableString(sourceContent,
                Smiley.TYPE_WEIBO, ContentUtils.SMILEY_SIZE);
    }

    /**
     * 解析话题
     * 
     * <br>
     * Created 2014-8-28 下午6:12:52
     * 
     * @param sourceContent
     *            要解析的内容
     * @param ss
     *            要解析的内容
     * @return SpannableString 解析后的内容
     * @author PanYun
     */
    public static SpannableString resolveHashtags(String sourceContent, SpannableString ss) {
        if (ss == null) {
            ss = new SpannableString(sourceContent);
        }
        Matcher m = WbRegexUtils.HASHTAGS_PATTERN.matcher(sourceContent);
        if (m.find()) { // 只解析第一个tag
            String hashtagsMatch = m.group();
            String subHashtagsMatch = hashtagsMatch.substring(0, hashtagsMatch.length());
            ss.setSpan(new URLSpanNoUnderline(subHashtagsMatch,
                    URLSpanNoUnderline.SpanType.HASHTAGS), m.start(), m.end(),
                    SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return ss;
    }

    /**
     * 根据textview创建带文字和背景的Drawable
     * 
     * Created 2014-8-28 上午11:42:04
     * 
     * @param context
     *            Context
     * @param textView
     *            设置好文字和背景的textview
     * @return Drawable 把需要整理的内容转成一个图片
     * @author PanYun
     */
    public static Drawable getImageSpanDrawble(Context context, TextView textView) {
        int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        textView.measure(spec, spec);
        textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
        Bitmap b = Bitmap.createBitmap(textView.getWidth(), textView.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(b);
        canvas.translate(-textView.getScrollX(), -textView.getScrollY());
        textView.draw(canvas);
        textView.setDrawingCacheEnabled(true);
        Bitmap cacheBmp = textView.getDrawingCache();
        Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
        textView.destroyDrawingCache(); // destory drawable
        BitmapDrawable bmpDrawable = new BitmapDrawable(context.getResources(), viewBmp);
        bmpDrawable.setBounds(0, 0, bmpDrawable.getIntrinsicWidth(),
                bmpDrawable.getIntrinsicHeight());
        return bmpDrawable;
    }

    /**
     * 
     * @n<b>函数名称</b> :getImageSpanDrawble
     * @brief 创建带文字和背景的Drawable,文字可以由外部传入，目前传null默认显示网页链接。
     *        另暂时只考虑微博短链接替换使用，其他地方使用可以进一步修改，由外部传入不同状态时的图片，图片大小，文字大小等等属性
     * @see
     * @since Ver 1.1
     * @param context
     *            Context
     * @param press
     *            是否按下状态
     * @param content
     *            要显示的内容
     * @return Drawable 创建的图片
     * @<b>作者</b> : huangszh
     * @<b>创建时间</b> : 2013-12-10下午5:12:57
     */
    public static Drawable getImageSpanDrawble(Context context, boolean press, String content) {
        LayoutInflater lf = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        TextView textView = (TextView) lf.inflate(R.layout.wblst_url_textview, null);
        if (content == null) {
            textView.setText(R.string.wblst_url_text);
        } else {
            textView.setText(content);
        }

        if (press) {
            textView.setBackgroundResource(R.drawable.wblst_url_bg_press);
        } else {
            textView.setBackgroundResource(R.drawable.wblst_url_bg_normal);
        }
        // textView.setCompoundDrawablesWithIntrinsicBounds(0, 0,
        // R.drawable.android, 0);
        return getImageSpanDrawble(context, textView);

    }

    /**
     * 
     * @n<b>函数名称</b> :setUrlImageSpan
     * @brief 用于微博短链接背景图片切换效果，重新设置ImageSpan
     * @see
     * @since Ver 1.1
     * @param widget
     *            TextView
     * @param imagespan
     *            UrlImageSpan
     * @param buffer
     *            buffer
     * @param press
     *            是否按下状态
     * @param content
     *            要显示的内容
     * @return UrlImageSpan url解析后的内容
     * @<b>作者</b> : huangszh
     * @<b>创建时间</b> : 2013-12-10下午5:13:05
     */
    public static UrlImageSpan setUrlImageSpan(TextView widget, UrlImageSpan imagespan,
            Spannable buffer, boolean press, String content) {
        int start = buffer.getSpanStart(imagespan);
        int end = buffer.getSpanEnd(imagespan);
        buffer.removeSpan(imagespan);
        // 找不到设置span的地方，直接返回null
        if (start == -1 || end == -1) {
            return null;
        }
        imagespan = new UrlImageSpan(getImageSpanDrawble(widget.getContext(), press, content));
        buffer.setSpan(imagespan, start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
        widget.setText(buffer);
        return imagespan;
    }

    /**
     * 
     * ClassName:UrlImageSpan Function: 用于与表情的ImageSpan区分 
     * 
     * @author huangszh
     * @version Utils
     * @since Ver 1.1
     * @Date 2013 2013-12-11 上午10:15:42
     * 
     * @see
     */
    public static class UrlImageSpan extends ImageSpan {
    	
    	private String mUrl; // url内容
    	
        /**
         * 
         * Creates a new instance of UrlImageSpan. <br>
         * Created 2014-8-28 下午6:27:17
         * 
         * @param d
         *            Drawable 图片
         */
        public UrlImageSpan(Drawable d) {
            super(d);
        }
        
        /**
         * 设置原始url内容
         * 
         * <br>Created 2014-11-5 上午10:59:27
         * @param url url
         * @author       huangszh
         */
        public void setUrl(String url){
        	mUrl = url;
		}
		
        /**
         * 获取原始url内容
         * 
         * <br>Created 2014-11-5 上午10:59:12
         * @return String
         * @author       huangszh
         */
		public String getUrl(){
			return mUrl;
		}
    }

    /**
     * 对应UrlImageSpan的配套点击事件；为了与@等使用的URLSpanNoUnderline区分
     * 
     * <br>Created 2014-11-4 下午6:20:13
     * @version  ContentUtils
     * @author   huangszh		
     *
     * @see 	 
     * 
     * Copyright(c) 2009-2014, TQ Digital Entertainment, All Rights Reserved
     *
     */
	public static class URLImageClickSpan extends  URLSpanNoUnderline{
		
		public URLImageClickSpan(String url) {
			this(url, SpanType.UNKNOW);
		}

		public URLImageClickSpan(String url, SpanType spanType) {
			super(url,spanType);
		}

		public URLImageClickSpan(String url, SpanType spanType, Object obj) {
			super(url, spanType,obj);
		}
	}
    
    /**
     * 可点击的解析
     * 
     * <br>
     * Created 2014-8-28 下午6:27:37
     * 
     * @version ContentUtils
     * @author PanYun
     * 
     * @see
     */
    public static class URLSpanNoUnderline extends URLSpan {
        protected SpanType mSpanType;
        protected Object mObj;

        /**
         * 
         * 
         * <br>
         * Created 2014-8-28 下午6:27:57
         * 
         * @version ContentUtils.URLSpanNoUnderline
         * @author PanYun
         * 
         * @see
         */
        public enum SpanType {
            URL, AT, SMILEY, HASHTAGS, UNKNOW
        }

        /**
         * 
         * Creates a new instance of URLSpanNoUnderline. <br>
         * Created 2014-8-28 下午6:28:06
         * 
         * @param url
         *            显示内容
         */
        public URLSpanNoUnderline(String url) {
            this(url, SpanType.UNKNOW);
        }

        /**
         * 
         * Creates a new instance of URLSpanNoUnderline. <br>
         * Created 2014-8-28 下午6:28:20
         * 
         * @param url
         *            要显示内容
         * @param spanType
         *            显示的类型
         */
        public URLSpanNoUnderline(String url, SpanType spanType) {
            super(url);
            mSpanType = spanType;
        }

        /**
         * 
         * Creates a new instance of URLSpanNoUnderline.
         * <br>Created 2014-8-29 上午10:02:32
         * @param url 要显示的内容
         * @param spanType 显示的类型
         * @param obj 带参数的对象
         */
        public URLSpanNoUnderline(String url, SpanType spanType, Object obj) {
            this(url, spanType);
            mObj = obj;
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);
            switch (mSpanType) {
            case HASHTAGS:
                ds.setColor(0xFFE76812);
                break;
            default:
                ds.setColor(0xFF3A7383);
                break;
            }

        }

        /**
         * 设置显示类型
         * 
         * <br>
         * Created 2014-8-28 下午7:20:58
         * 
         * @return SpanType 显示类型
         * @author PanYun
         */
        public SpanType getSpanType() {
            return mSpanType;
        }

        @Override
        public boolean equals(Object o) {

            if (o instanceof URLSpanNoUnderline) {
                URLSpanNoUnderline us = (URLSpanNoUnderline) o;
                if (us.mSpanType.equals(mSpanType) && us.getURL().equals(getURL())) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public int hashCode() {
            return super.hashCode();
        }

        @Override
        public void onClick(View widget) { // 自定义
            Context context = widget.getContext();
            Intent intent = new Intent();
            String url = getURL();
            switch (mSpanType) {
            case URL:
                intent.setClass(context, WebViewActivity.class);
                intent.putExtra(WebViewActivity.EXTARS_WEBVIEW_RETURN, false);
                intent.putExtra(WebViewActivity.EXTARS_WEBVIEW_URL, url);
                intent.putExtra(WebViewActivity.EXTARS_WEBVIEW_NEED_TITLE, false);
                context.startActivity(intent);
                break;
            case AT:
                if (mObj instanceof Long) {
                    long uid = ((Long) mObj).longValue();
                    AllCommonCallOtherModel.WeiboModel.gotoTweetProfileActivity((Activity) context,
                            uid);
                }
                break;
            case HASHTAGS:
                if (url.length() > 1) {
                    String tagName = url.substring(1, url.length() - 1);
                    AllCommonCallOtherModel.WeiboModel.gotoHashTagsListActivity((Activity) context,
                            tagName);

                }
                break;
            case SMILEY:
                break;
            case UNKNOW:
            default:
            }

        }
    }

    /**
     * 
     * @n<b>函数名称</b> :getWordCount
     * @brief 获得微博字数，汉字算1个，半角英文数字符号等算0.5个
     * @see
     * @since Ver 1.1
     * @param sourceStr
     *            原微博内容
     * @param flag
     *            是否计算剔除URL和<M></M>标签,flag = false的情况下， float[1]无意义
     * @param maxLength
     *            最长限制长度
     * @return float[] float[0]是字符串的长度 float[1]是字符串的长度到达140时的实际文字数，这个文字数是不论汉字英文数字都算1个的,而且没有提出url和M标签
     * @<b>作者</b> : chenqian
     * @<b>创建时间</b> : 2014-1-13下午2:48:18
     */
    public static float[] getWordCount(final String sourceStr, final boolean flag,
            final int maxLength) {
        String processStr = sourceStr;
        if (flag) {
            processStr = getNotUrlString(processStr);
            processStr = WbAtView.getOnlyAtContent(processStr);// 剔除<M XXX></M>
        }
        // sourceStr:未处理的字符串
        // processStr:处理的字符串
        // len[0]:按照汉字为1，其他为0.5的规则，计算processStr的长度
        // len[1]:计算processStr的长度,直到len[0]长度超过MAX_SIZE_OF_TWEET
        float len[] = new float[2];
        int ascii1, ascii2;
        int j = 0;
        for (int i = 0; i < processStr.length(); ++i) {
            // ascii1:取处理串的每个ascii码
            ascii1 = Character.codePointAt(processStr, i);
            if (ascii1 >= 0 && ascii1 <= 255) {// 如果在ascii码范围内，则计算长度为0.5
                len[0] += 0.5;
            } else {
                ++len[0];// 否则计算长度为1
            }

            if (flag && len[0] <= maxLength) {
                // ascii2:取原串的每个ascii码
                ascii2 = Character.codePointAt(sourceStr, j);

                // 如果原串的ascii码和处理串的ascii码不相等，则后移取原串取下一个ascii码,直到相等
                while (ascii1 != ascii2 && j < sourceStr.length()) {
                    ++j;
                    ascii2 = Character.codePointAt(sourceStr, j);
                }
                // 如果原串的ascii码和处理串的ascii码相等，则原串和处理串都向后移动一位继续比较
                if (ascii1 == ascii2 && j < sourceStr.length()) {
                    ++j;
                }
            }
        }
        len[1] = j;
        return len;
    }

    /**
     * 
     * @n<b>函数名称</b> :getNotUrlString
     * @brief 长微博时，计算非URL的字符串长度
     * @see
     * @since Ver 1.1
     * @param str
     *            待计算的内容
     * @return String 解析后的内容
     * @<b>作者</b> : chenqian
     * @<b>创建时间</b> : 2014-1-14下午5:15:02
     */
    public static String getNotUrlString(String str) {
        int start = 0;
        int end = 0;
        StringBuilder sb = new StringBuilder();
        Matcher m = UrlUtils.WEB_URL.matcher(str);
        // 加入开头的非URL串
        if (m.find()) {
            start = m.start();
            end = m.end();
            if (start > 0) {
                sb.append(str.substring(0, start));
            }
        }
        // 加入中间的非URL串
        while (m.find()) {
            start = m.start();
            if (end < start) {
                sb.append(str.substring(end, start));
            }
            end = m.end();
        }
        // 加入结尾的非URL串
        if (end < str.length()) {
            sb.append(str.substring(end));
        }
        return sb.toString();
    }
    
    /**
     * 
     * @n<b>函数名称</b>     :processLongTweet
     * @brief 处理长微博，如果maxLength的位置处有@，url，表情，话题，则取这些字段前面的文字,
     * 但是即使经过处理，也无法和服务端的截断完全一致，因为服务端对url长度进行了转化，而我们是完全不计算在内
     * @see
     * @since    Ver 1.1
     * @param  @param longText 文本内容
     * @param maxLength 最大长度
     * @param  @return
     * @return String
     * @<b>作者</b>          :  chenqian
     * @<b>创建时间</b>      :  2014-3-17下午4:25:53
     */
    public static String processLongTweet(String longText, int maxLength) {
        if(TextUtils.isEmpty(longText)){
            return longText;
        }
        float[] len = getWordCount(longText, true,maxLength);//去除了url和<M>标签
        try{
            if(len[0] <= maxLength){
                return longText;
            }
            
            StringBuilder retStr = new StringBuilder("...");
            // 防止@截断
            int atStart = findAt(longText, (int) len[1]);
            if(atStart > 0){
                return retStr.insert(0, longText.substring(0, atStart)).toString();
            }

            // 防止表情截断
            String shortText = longText.substring(0, (int) len[1]);
            int left = shortText.lastIndexOf("[");
            if(left > 0){
                String restText = longText.substring(left + 1);
                int right = restText.indexOf("]") +(left + 1) + 1;
                if(right > len[1] && right - left < 6){// 防止表情被截断，目前表情最多由5个字节组成
                    return retStr.insert(0, longText.substring(0, left)).toString();
                }
            }

            // 防止url截断
            // 找出全部的url,记录下，判断MAX_SIZE_OF_TWEET是否落在其中，是的话，截取到该URL开始
            int urlStart = findUrl(longText, (int) len[1]);
            if(urlStart > 0){
                return retStr.insert(0, longText.substring(0, urlStart)).toString();
            }

            //防止话题截断
            int tagStart = findHashtag(longText, (int) len[1]);
            if(tagStart > 0){
                return retStr.insert(0, longText.substring(0, tagStart)).toString();
            }
            
            // 取结束值的最大
            return retStr.insert(0,  longText.substring(0, (int) len[1])).toString();
        }catch(StringIndexOutOfBoundsException e){
            return longText;
        }
    }
    
  
    
    /**
     * 
     * @n<b>函数名称</b>     :findAt
     * @brief
     * @see
     * @since    Ver 1.1
     * @param  @param sourceContent
     * @param  @param end
     * @param  @return >0 代表找到at串，<0 代表没找到,否则返回AT串的起始位置
     * @return int
     * @<b>作者</b>          :  chenqian
     * @<b>创建时间</b>      :  2014-1-17下午1:54:54
     */
    private static int findAt(String sourceContent, int end) {
        Matcher m = WbRegexUtils.AT_M_TAG_PATTERN.matcher(sourceContent);
        while (m.find()) {
            if (m.start() > end) {
                break;
            }
            if (m.start() < end && m.end() >= end) {
                return m.start();
            }
        }
        return -1;
    }
    
    /**
     * 
     * @n<b>函数名称</b> :findUrl
     * @brief 长微博时，计算最大值附近的URL，避免截断，如果URL落在中间，则截取到该URL开始位置之前
     * @see
     * @since Ver 1.1
     * @param @param sourceContent
     * @param @param end
     * @param @return
     * @return int
     * @<b>作者</b> : huangszh
     * @<b>创建时间</b> : 2013-12-11下午5:15:02
     */
    private static int findUrl(String sourceContent, int end) {
        Matcher m = UrlUtils.WEB_URL.matcher(sourceContent);
        while (m.find()) {
            if (m.start() > end) {
                break;
            }
            if (m.start() < end && m.end() >= end) {
                return m.start();
            }
        }
        return -1;
    }
    
    /**
     * 
     * @n<b>函数名称</b>     :findHashtag
     * @brief 微博时，计算最大值附近的话题，避免截断，如果话题落在中间，则截取到该话题位置之前
     * @see
     * @since    Ver 1.1
     * @param  @param sourceContent
     * @param  @param end
     * @param  @return
     * @return int
     * @<b>作者</b>          :  chenqian
     * @<b>创建时间</b>      :  2014-3-17下午4:30:16
     */
    private static int findHashtag(String sourceContent, int end){
        Matcher m = WbRegexUtils.HASHTAGS_PATTERN.matcher(sourceContent);
        while (m.find()) {
            if (m.start() > end) {
                break;
            }
            if (m.start() < end && m.end() >= end) {
                return m.start();
            }
        }
        return -1;
    }
}
